<?php
/**
 *
 *
 */
namespace Yz\modules\Users;

use Yz_Array,
    Error,
    AccessError,
    NotFoundError,
    Yz\modules\Captcha,
    Yz_Hash;

class Controller_Login
    extends \Yz_Controller_Templated
{

    protected $loginFailure = false;
    protected $captchaFailure = false;
    protected $captchaEnabled;
    protected $fromURL;

    protected $modelName;


    /**
     *
     */
    public function doGet(Yz_Array $args)
    {
        debug();

        $this->fromURL = $this->getRequest()->fetchArgument('path');

        $template = $this->selectTemplate();

        $template->fromURL = $this->fromURL;
        $template->loginFailure = $this->loginFailure;
        $template->captchaFailure = $this->captchaFailure;
        $template->captchaEnabled = $this->captchaEnabled();

        return $this->outputTemplate($template);
    }


    /**
     *
     *
     */
    public function doPOST(Yz_Array $args, Yz_Hash $post)
    {
        debug();
        // implicit logout
        $this ->checkAccess() ;

        $this->testCaptcha($post);

        $login = $post->offsetGet('login');
        // throws not found
        $userObject = $this->module
            ->selectModel($this->modelName)
            ->fetchUserByLogin($login)
        ;

        $password = $post->offsetGet('password');

        if (! $userObject->verifyPassword($password))
            throw NotFoundError::_new_();
        $userObject
            ->offsetSet('lastLoginIP', $this->getRequest()->getRemoteAddr())
            ->offsetSet('lastLoginTime', (int)YZ_TIME)
            ->save()
        ;

        $user = \Yz_User_Default::getInstance();
        $user->login($userObject);

        $rq = $this->getRequest();
        $url = $rq->fetchArgument("path", $rq->getWebPrefix());
        $this->getView()
            ->setRedirect( $url )
        ;
        return $this;
    }


    /**
     *  @todo
     */
    public function doError(Error $ex)
    {
        debug();

        switch (true) {
            case $ex instanceof AccessError:
                // in case of forced logout
                break;
            case $ex instanceof Captcha\Error:
                $this->captchaFailure = true;
                break;
            case $ex instanceof NotFoundError:
                $this->loginFailure = true;
                break;
            default:
                // unhandled error
                return false;
        }
        return $this->doGet(new Yz_Array);
    }


    /**
     *
     */
    protected function checkAccess()
    {
        debug();

        $user = \Yz_User_Default::getInstance();
        if ($user->isAuthenticated()) {
            $user->logout();
            throw AccessError::_new_(array('path' => 'login'));
        }

        return $this;
    }


    /**
     *
     *  @return bool
     *
     */
    protected function testCaptcha(Yz_Hash $post)
    {
        debug();

        if ($this->captchaEnabled()) {
            $code = $post->offsetGet('captcha');
            if (null === $code)
                throw Captcha\Error::_new_();
            $captModule = \Yz::selectModule("Captcha");
            $captcha = $captModule->selectModel("Captcha");
            return $captcha->verifyCode($code);
        }
        return true;
    }

    /**
     *  @return bool
     *  @todo the config value is definitely the concern of the Captcha module
     */
    protected function captchaEnabled()
    {
        debug();
        $r =& $this->captchaEnabled;
        if (null === $r)
            $r = \Yz::getConfig()->fetchBoolean("users.login.captcha.enabled");
        return $r;
    }

}
